<template>
  <div class="farm-3d">
    <div class="farm-container">
      <!-- 3D场景容器 -->
      <div ref="threeContainer" class="three-container"></div>
      
      <!-- 控制面板 -->
      <div class="control-panel">
        <el-card class="control-card">
          <template #header>
            <div class="card-header">
              <el-icon><Control /></el-icon>
              <span>场景控制</span>
            </div>
          </template>
          
          <div class="control-group">
            <label>视角控制</label>
            <el-button-group>
              <el-button size="small" @click="setCameraView('top')">俯视</el-button>
              <el-button size="small" @click="setCameraView('side')">侧视</el-button>
              <el-button size="small" @click="setCameraView('front')">前视</el-button>
            </el-button-group>
          </div>
          
          <div class="control-group">
            <label>显示选项</label>
            <el-checkbox v-model="showGrid" @change="toggleGrid">网格</el-checkbox>
            <el-checkbox v-model="showLabels" @change="toggleLabels">标签</el-checkbox>
            <el-checkbox v-model="showWeather" @change="toggleWeather">天气效果</el-checkbox>
          </div>
          
          <div class="control-group">
            <label>时间控制</label>
            <el-slider
              v-model="timeOfDay"
              :min="0"
              :max="24"
              :step="0.5"
              @change="updateTimeOfDay"
              show-input
            />
          </div>
        </el-card>
        
        <!-- 智能功能区 -->
        <el-card class="ai-card">
          <template #header>
            <div class="card-header">
              <el-icon><Cpu /></el-icon>
              <span>智能功能</span>
            </div>
          </template>
          <div class="ai-group">
            <el-button type="primary" size="small" @click="startVehiclePatrol">
              <el-icon><Van /></el-icon>
              启动农机巡检
            </el-button>
            <el-button size="small" @click="openAIUploadDialog">
              <el-icon><Picture /></el-icon>
              AI病虫害识别
            </el-button>
            <el-divider />
            <div class="irrigation-section">
              <div class="irrigation-title">
                <el-icon><Watermelon /></el-icon>
                智能灌溉
              </div>
              <div class="irrigation-info">
                当前土壤湿度：<span class="status-info">{{ soilMoisture }}%</span>
              </div>
              <div class="irrigation-recommend">
                推荐：<span class="status-success">{{ irrigationAdvice }}</span>
              </div>
              <el-button type="success" size="small" @click="toggleIrrigation">
                <el-icon><SwitchButton /></el-icon>
                {{ irrigationActive ? '停止灌溉' : '一键灌溉' }}
              </el-button>
            </div>
          </div>
        </el-card>

        <el-card class="info-card">
          <template #header>
            <div class="card-header">
              <el-icon><InfoFilled /></el-icon>
              <span>农场信息</span>
            </div>
          </template>
          
          <div class="info-item">
            <span class="label">总面积:</span>
            <span class="value">50亩</span>
          </div>
          <div class="info-item">
            <span class="label">种植区域:</span>
            <span class="value">8个</span>
          </div>
          <div class="info-item">
            <span class="label">当前作物:</span>
            <span class="value">水稻、玉米、蔬菜</span>
          </div>
          <div class="info-item">
            <span class="label">设备状态:</span>
            <span class="value status-normal">正常</span>
          </div>
        </el-card>
      </div>
    </div>

    <!-- AI识别上传对话框 -->
    <el-dialog v-model="aiDialogVisible" title="AI病虫害识别" width="400px">
      <el-upload
        class="upload-demo"
        drag
        action="#"
        :auto-upload="false"
        :on-change="handleAIFileChange"
        :file-list="aiFileList"
        :limit="1"
        accept="image/*"
      >
        <i class="el-icon--upload"><el-icon><Picture /></el-icon></i>
        <div class="el-upload__text">拖拽或点击上传作物图片</div>
      </el-upload>
      <template #footer>
        <el-button @click="aiDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="runAIRecognition">识别</el-button>
      </template>
    </el-dialog>
    <!-- AI识别结果弹窗 -->
    <el-dialog v-model="aiResultVisible" title="AI识别结果" width="400px" :show-close="true">
      <div v-if="aiResult">
        <div class="ai-result-label">识别结果：</div>
        <div class="ai-result-main">
          <el-tag :type="aiResult.level === 'warning' ? 'warning' : 'danger'" size="large">
            {{ aiResult.disease }}
          </el-tag>
        </div>
        <div class="ai-result-desc">{{ aiResult.suggestion }}</div>
      </div>
      <div v-else>暂无识别结果</div>
      <template #footer>
        <el-button type="primary" @click="aiResultVisible = false">关闭</el-button>
      </template>
    </el-dialog>
    <!-- 巡检报告弹窗 -->
    <el-dialog v-model="patrolReportVisible" title="农机巡检报告" width="500px">
      <div>
        <el-timeline>
          <el-timeline-item
            v-for="(item, idx) in patrolReport"
            :key="idx"
            :timestamp="item.time"
            :type="item.level"
          >
            {{ item.desc }}
          </el-timeline-item>
        </el-timeline>
      </div>
      <template #footer>
        <el-button type="primary" @click="patrolReportVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

export default {
  name: 'Farm3D',
  data() {
    return {
      showGrid: true,
      showLabels: true,
      showWeather: false,
      timeOfDay: 12,
      animationId: null,
      // 智能功能相关
      soilMoisture: 45,
      irrigationAdvice: '',
      irrigationActive: false,
      aiDialogVisible: false,
      aiFileList: [],
      aiResultVisible: false,
      aiResult: null,
      patrolReportVisible: false,
      patrolReport: [],
      vehiclePatrolActive: false
    }
  },
  mounted() {
    this.initThreeJS()
    this.createScene()
    this.animate()
    this.updateIrrigationAdvice()
  },
  beforeUnmount() {
    if (this.animationId) {
      cancelAnimationFrame(this.animationId)
    }
    if (this.renderer) {
      this.renderer.dispose()
    }
  },
  methods: {
    initThreeJS() {
      const container = this.$refs.threeContainer
      // Three.js对象直接挂载到this上，避免Vue响应式代理
      this.scene = new THREE.Scene()
      this.scene.background = new THREE.Color(0x87CEEB)
      this.camera = new THREE.PerspectiveCamera(
        75,
        container.clientWidth / container.clientHeight,
        0.1,
        1000
      )
      this.camera.position.set(50, 30, 50)
      this.renderer = new THREE.WebGLRenderer({ antialias: true })
      this.renderer.setSize(container.clientWidth, container.clientHeight)
      this.renderer.shadowMap.enabled = true
      this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
      container.appendChild(this.renderer.domElement)
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
      this.controls.enableDamping = true
      this.controls.dampingFactor = 0.05
      window.addEventListener('resize', this.onWindowResize)
    },
    
    createScene() {
      // 添加环境光
      const ambientLight = new THREE.AmbientLight(0x404040, 0.6)
      this.scene.add(ambientLight)
      
      // 添加方向光（太阳）
      const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
      directionalLight.position.set(50, 50, 50)
      directionalLight.castShadow = true
      directionalLight.shadow.mapSize.width = 2048
      directionalLight.shadow.mapSize.height = 2048
      this.scene.add(directionalLight)
      
      // 创建地面
      this.createGround()
      
      // 创建农田
      this.createFarmland()
      
      // 创建建筑物
      this.createBuildings()
      
      // 创建设备
      this.createEquipment()
      
      // 创建网格
      this.createGrid()
      this.createVehicle() // 农机
    },
    
    createGround() {
      const groundGeometry = new THREE.PlaneGeometry(200, 200)
      const groundMaterial = new THREE.MeshLambertMaterial({ 
        color: 0x90EE90,
        transparent: true,
        opacity: 0.8
      })
      const ground = new THREE.Mesh(groundGeometry, groundMaterial)
      ground.rotation.x = -Math.PI / 2
      ground.receiveShadow = true
      this.scene.add(ground)
    },
    
    createFarmland() {
      // 创建8个农田区域
      const farmAreas = [
        { x: -60, z: -60, crop: 'rice' },
        { x: 0, z: -60, crop: 'corn' },
        { x: 60, z: -60, crop: 'vegetables' },
        { x: -60, z: 0, crop: 'wheat' },
        { x: 0, z: 0, crop: 'soybeans' },
        { x: 60, z: 0, crop: 'cotton' },
        { x: -60, z: 60, crop: 'fruits' },
        { x: 60, z: 60, crop: 'flowers' }
      ]
      
      farmAreas.forEach((area, index) => {
        this.createFarmArea(area.x, area.z, area.crop, index)
      })
    },
    
    createFarmArea(x, z, cropType, index) {
      // 农田基础
      const farmGeometry = new THREE.PlaneGeometry(25, 25)
      const farmMaterial = new THREE.MeshLambertMaterial({ 
        color: this.getCropColor(cropType)
      })
      const farm = new THREE.Mesh(farmGeometry, farmMaterial)
      farm.position.set(x, 0.1, z)
      farm.rotation.x = -Math.PI / 2
      farm.receiveShadow = true
      this.scene.add(farm)
      
      // 添加作物
      this.createCrops(x, z, cropType)
      
      // 添加标签
      if (this.showLabels) {
        this.createLabel(x, z + 15, `${cropType} Area ${index + 1}`)
      }
    },
    
    createCrops(x, z, cropType) {
      const cropCount = 20
      const cropGeometry = new THREE.CylinderGeometry(0.2, 0.2, 2)
      const cropMaterial = new THREE.MeshLambertMaterial({ 
        color: this.getCropColor(cropType) 
      })
      
      for (let i = 0; i < cropCount; i++) {
        const crop = new THREE.Mesh(cropGeometry, cropMaterial)
        const offsetX = (Math.random() - 0.5) * 20
        const offsetZ = (Math.random() - 0.5) * 20
        crop.position.set(x + offsetX, 1, z + offsetZ)
        crop.castShadow = true
        this.scene.add(crop)
      }
    },
    
    createBuildings() {
      // 主建筑
      const buildingGeometry = new THREE.BoxGeometry(10, 8, 15)
      const buildingMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 })
      const building = new THREE.Mesh(buildingGeometry, buildingMaterial)
      building.position.set(-80, 4, 0)
      building.castShadow = true
      this.scene.add(building)
      
      // 温室
      const greenhouseGeometry = new THREE.BoxGeometry(15, 6, 20)
      const greenhouseMaterial = new THREE.MeshLambertMaterial({ 
        color: 0x90EE90,
        transparent: true,
        opacity: 0.3
      })
      const greenhouse = new THREE.Mesh(greenhouseGeometry, greenhouseMaterial)
      greenhouse.position.set(80, 3, 0)
      greenhouse.castShadow = true
      this.scene.add(greenhouse)
    },
    
    createEquipment() {
      // 灌溉设备
      const sprinklerGeometry = new THREE.CylinderGeometry(1, 1, 3)
      const sprinklerMaterial = new THREE.MeshLambertMaterial({ color: 0x4169E1 })
      const sprinkler = new THREE.Mesh(sprinklerGeometry, sprinklerMaterial)
      sprinkler.position.set(0, 1.5, -80)
      sprinkler.castShadow = true
      this.scene.add(sprinkler)
      
      // 传感器
      const sensorGeometry = new THREE.SphereGeometry(0.5)
      const sensorMaterial = new THREE.MeshLambertMaterial({ color: 0xFF4500 })
      for (let i = 0; i < 4; i++) {
        const sensor = new THREE.Mesh(sensorGeometry, sensorMaterial)
        sensor.position.set(
          (Math.random() - 0.5) * 100,
          0.5,
          (Math.random() - 0.5) * 100
        )
        this.scene.add(sensor)
      }
    },
    
    createGrid() {
      if (this.showGrid) {
        const gridHelper = new THREE.GridHelper(200, 20, 0x888888, 0x888888)
        this.scene.add(gridHelper)
      }
    },
    
    createLabel(x, z, text) {
      const canvas = document.createElement('canvas')
      const context = canvas.getContext('2d')
      canvas.width = 256
      canvas.height = 64
      
      context.fillStyle = 'rgba(0, 0, 0, 0.8)'
      context.fillRect(0, 0, canvas.width, canvas.height)
      
      context.fillStyle = 'white'
      context.font = '24px Arial'
      context.textAlign = 'center'
      context.fillText(text, canvas.width / 2, canvas.height / 2 + 8)
      
      const texture = new THREE.CanvasTexture(canvas)
      const material = new THREE.SpriteMaterial({ map: texture })
      const sprite = new THREE.Sprite(material)
      sprite.position.set(x, 10, z)
      sprite.scale.set(10, 2.5, 1)
      this.scene.add(sprite)
    },
    
    getCropColor(cropType) {
      const colors = {
        rice: 0x90EE90,
        corn: 0xFFD700,
        vegetables: 0x32CD32,
        wheat: 0xF5DEB3,
        soybeans: 0x8B4513,
        cotton: 0xFFFFFF,
        fruits: 0xFF6347,
        flowers: 0xFF69B4
      }
      return colors[cropType] || 0x90EE90
    },
    
    animate() {
      this.animationId = requestAnimationFrame(this.animate)
      this.controls.update()
      this.renderer.render(this.scene, this.camera)
    },
    
    onWindowResize() {
      const container = this.$refs.threeContainer
      this.camera.aspect = container.clientWidth / container.clientHeight
      this.camera.updateProjectionMatrix()
      this.renderer.setSize(container.clientWidth, container.clientHeight)
    },
    
    setCameraView(view) {
      switch (view) {
        case 'top':
          this.camera.position.set(0, 100, 0)
          this.camera.lookAt(0, 0, 0)
          break
        case 'side':
          this.camera.position.set(100, 0, 0)
          this.camera.lookAt(0, 0, 0)
          break
        case 'front':
          this.camera.position.set(0, 0, 100)
          this.camera.lookAt(0, 0, 0)
          break
      }
    },
    
    toggleGrid() {
      this.scene.children = this.scene.children.filter(child => 
        !(child instanceof THREE.GridHelper)
      )
      if (this.showGrid) {
        this.createGrid()
      }
    },
    
    toggleLabels() {
      // 简单的标签切换实现
      console.log('Toggle labels:', this.showLabels)
    },
    
    toggleWeather() {
      // 天气效果切换
      console.log('Toggle weather:', this.showWeather)
    },
    
    updateTimeOfDay(time) {
      // 根据时间调整光照
      const intensity = time > 6 && time < 18 ? 0.8 : 0.2
      this.scene.children.forEach(child => {
        if (child instanceof THREE.DirectionalLight) {
          child.intensity = intensity
        }
      })
    },
    // 新增：农机模型与动画
    createVehicle() {
      // 简单农机模型（长方体+轮子）
      const bodyGeometry = new THREE.BoxGeometry(4, 2, 2)
      const bodyMaterial = new THREE.MeshLambertMaterial({ color: 0x2196f3 })
      this.vehicle = new THREE.Mesh(bodyGeometry, bodyMaterial)
      this.vehicle.position.set(-80, 1, -80)
      this.vehicle.castShadow = true
      this.scene.add(this.vehicle)
      // 轮子
      const wheelGeometry = new THREE.CylinderGeometry(0.5, 0.5, 0.8, 16)
      const wheelMaterial = new THREE.MeshLambertMaterial({ color: 0x333333 })
      for (let i = 0; i < 4; i++) {
        const wheel = new THREE.Mesh(wheelGeometry, wheelMaterial)
        wheel.rotation.z = Math.PI / 2
        wheel.position.set(
          this.vehicle.position.x + (i < 2 ? -1.5 : 1.5),
          0.5,
          this.vehicle.position.z + (i % 2 === 0 ? -0.8 : 0.8)
        )
        this.scene.add(wheel)
        if (!this.vehicle.wheels) this.vehicle.wheels = []
        this.vehicle.wheels.push(wheel)
      }
      // 巡检路径
      this.patrolPath = [
        { x: -80, z: -80 },
        { x: 80, z: -80 },
        { x: 80, z: 80 },
        { x: -80, z: 80 },
        { x: -80, z: -80 }
      ]
      this.patrolIndex = 0
      this.patrolProgress = 0
    },
    startVehiclePatrol() {
      if (this.vehiclePatrolActive) return
      this.vehiclePatrolActive = true
      this.patrolIndex = 0
      this.patrolProgress = 0
      this.patrolReport = []
      this.animateVehiclePatrol()
    },
    animateVehiclePatrol() {
      if (!this.vehiclePatrolActive) return
      const from = this.patrolPath[this.patrolIndex]
      const to = this.patrolPath[(this.patrolIndex + 1) % this.patrolPath.length]
      const speed = 0.5
      // 插值移动
      this.patrolProgress += speed
      const t = Math.min(this.patrolProgress / 100, 1)
      this.vehicle.position.x = from.x + (to.x - from.x) * t
      this.vehicle.position.z = from.z + (to.z - from.z) * t
      // 轮子同步
      if (this.vehicle.wheels) {
        this.vehicle.wheels.forEach(w => {
          w.position.x = this.vehicle.position.x + (w.position.x < this.vehicle.position.x ? -1.5 : 1.5)
          w.position.z = this.vehicle.position.z + (w.position.z < this.vehicle.position.z ? -0.8 : 0.8)
        })
      }
      if (t >= 1) {
        // 到达下一个点
        this.patrolIndex = (this.patrolIndex + 1) % this.patrolPath.length
        this.patrolProgress = 0
        // 模拟巡检报告
        this.patrolReport.push({
          time: new Date().toLocaleTimeString(),
          desc: `巡检到达点(${to.x}, ${to.z})，状态正常`,
          level: 'success'
        })
        if (this.patrolIndex === 0) {
          // 完成一圈
          this.vehiclePatrolActive = false
          this.patrolReport.push({
            time: new Date().toLocaleTimeString(),
            desc: '巡检完成，无异常',
            level: 'info'
          })
          this.patrolReportVisible = true
          return
        }
      }
      requestAnimationFrame(this.animateVehiclePatrol)
    },
    // 智能灌溉
    updateIrrigationAdvice() {
      if (this.soilMoisture < 40) {
        this.irrigationAdvice = '建议立即灌溉'
      } else if (this.soilMoisture < 60) {
        this.irrigationAdvice = '适量灌溉'
      } else {
        this.irrigationAdvice = '无需灌溉'
      }
    },
    toggleIrrigation() {
      this.irrigationActive = !this.irrigationActive
      if (this.irrigationActive) {
        this.$message.success('智能灌溉已启动')
        setTimeout(() => {
          this.soilMoisture += 10
          this.updateIrrigationAdvice()
          this.irrigationActive = false
          this.$message.success('灌溉完成，土壤湿度提升')
        }, 2000)
      } else {
        this.$message.info('已停止灌溉')
      }
    },
    // AI识别
    openAIUploadDialog() {
      this.aiDialogVisible = true
      this.aiFileList = []
      this.aiResult = null
    },
    handleAIFileChange(file) {
      this.aiFileList = [file]
    },
    runAIRecognition() {
      if (!this.aiFileList.length) {
        this.$message.warning('请上传图片')
        return
      }
      // 模拟AI识别
      setTimeout(() => {
        this.aiResult = {
          disease: '稻瘟病',
          level: 'warning',
          suggestion: '建议立即喷洒专用药剂，并加强田间管理。'
        }
        this.aiDialogVisible = false
        this.aiResultVisible = true
      }, 1200)
    }
  }
}
</script>

<style scoped>
.farm-3d {
  height: 100%;
  position: relative;
}

.farm-container {
  display: flex;
  height: 100%;
  gap: 20px;
}

.three-container {
  flex: 1;
  height: 100%;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.control-panel {
  width: 300px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.control-card,
.info-card {
  height: fit-content;
}

.card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}

.control-group {
  margin-bottom: 20px;
}

.control-group label {
  display: block;
  margin-bottom: 8px;
  font-weight: 500;
  color: #606266;
}

.control-group .el-checkbox {
  display: block;
  margin-bottom: 8px;
}

.info-item {
  display: flex;
  justify-content: space-between;
  margin-bottom: 12px;
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
}

.info-item:last-child {
  border-bottom: none;
}

.info-item .label {
  color: #606266;
  font-weight: 500;
}

.info-item .value {
  color: #303133;
  font-weight: 600;
}

.status-normal {
  color: #67C23A;
}
</style> 